# API视图 - 为移动端和PWA提供数据接口
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404
from django.db.models import Q
from django.core.paginator import Paginator
import json

from .models import Asset, AssetCategory, Department, Location, AssetBorrow, MaintenanceRecord, Supplier, Contract
from .models_system import SystemNotification

# DRF Imports
from rest_framework import viewsets, permissions
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiTypes
from .serializers import AssetSerializer, DepartmentSerializer, LocationSerializer, SupplierSerializer, ContractSerializer

class AssetViewSet(viewsets.ModelViewSet):
    """
    一个用于查看和编辑资产实例的ViewSet。
    提供了 list, retrieve, create, update, destroy 等操作。
    """
    queryset = Asset.objects.select_related('category', 'department', 'location', 'user', 'ledger', 'ledger__organization').all()
    serializer_class = AssetSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        """可以根据请求参数动态过滤查询集"""
        queryset = super().get_queryset()
        user = self.request.user
        # 权限范围：若用户不是超级用户，则限定其可见范围
        if user.is_authenticated and not user.is_superuser:
            profile = getattr(user, 'profile', None)
            if profile:
                allowed_ledger_ids = list(profile.allowed_ledgers.values_list('id', flat=True))
                allowed_org_ids = list(profile.allowed_organizations.values_list('id', flat=True))
                if allowed_ledger_ids or allowed_org_ids:
                    scope_q = Q(ledger_id__in=allowed_ledger_ids)
                    if allowed_org_ids:
                        scope_q = scope_q | Q(ledger__organization_id__in=allowed_org_ids)
                    queryset = queryset.filter(scope_q)
                # 若两者都为空，则不限制（表示未配置专属范围）
        status = self.request.query_params.get('status')
        category_id = self.request.query_params.get('category')
        ledger_id = self.request.query_params.get('ledger')
        organization_id = self.request.query_params.get('organization')

        if status:
            queryset = queryset.filter(status=status)
        if category_id:
            queryset = queryset.filter(category_id=category_id)
        if ledger_id:
            queryset = queryset.filter(ledger_id=ledger_id)
        if organization_id:
            queryset = queryset.filter(ledger__organization_id=organization_id)
        
        return queryset


class DepartmentViewSet(viewsets.ModelViewSet):
    """
    一个用于查看和编辑部门实例的ViewSet。
    """
    queryset = Department.objects.all()
    serializer_class = DepartmentSerializer
    permission_classes = [permissions.IsAuthenticated]


class LocationViewSet(viewsets.ModelViewSet):
    """
    一个用于查看和编辑位置实例的ViewSet。
    """
    queryset = Location.objects.all()
    serializer_class = LocationSerializer
    permission_classes = [permissions.IsAuthenticated]


class SupplierViewSet(viewsets.ModelViewSet):
    """
    一个用于查看和编辑供应商实例的ViewSet。
    """
    queryset = Supplier.objects.all()
    serializer_class = SupplierSerializer
    permission_classes = [permissions.IsAuthenticated]


class ContractViewSet(viewsets.ModelViewSet):
    """
    一个用于查看和编辑合同实例的ViewSet。
    """
    queryset = Contract.objects.all()
    serializer_class = ContractSerializer
    permission_classes = [permissions.IsAuthenticated]


@extend_schema(
    summary="资产搜索API",
    description="支持二维码扫描和手动搜索",
    parameters=[
        OpenApiParameter(name='q', description='搜索关键词', type=OpenApiTypes.STR, required=True),
    ],
    responses={
        200: OpenApiTypes.OBJECT,
    }
)
@require_http_methods(["GET"])
def asset_search_api(request):
    """资产搜索API - 支持二维码扫描和手动搜索"""
    query = request.GET.get('q', '').strip()
    
    if not query:
        return JsonResponse({
            'success': False,
            'message': '请提供搜索关键词'
        })
    
    try:
        # 首先尝试精确匹配资产编号
        asset = Asset.objects.select_related(
            'category', 'department', 'location', 'user'
        ).filter(asset_number=query).first()
        
        if not asset:
            # 如果没有精确匹配，尝试模糊搜索
            assets = Asset.objects.select_related(
                'category', 'department', 'location', 'user'
            ).filter(
                Q(asset_number__icontains=query) |
                Q(name__icontains=query)
            )[:5]  # 限制返回5个结果
            
            if assets.exists():
                asset = assets.first()  # 取第一个结果
            else:
                return JsonResponse({
                    'success': False,
                    'message': f'未找到资产: {query}'
                })
        
        # 构建返回数据
        asset_data = {
            'id': asset.id,
            'asset_number': asset.asset_number,
            'name': asset.name,
            'category': asset.category.name if asset.category else '',
            'department': asset.department.name if asset.department else '',
            'location': asset.location.name if asset.location else '',
            'user': asset.user.username if asset.user else '',
            'status': asset.status,
            'status_display': asset.get_status_display(),
            'purchase_date': asset.purchase_date.strftime('%Y-%m-%d') if asset.purchase_date else '',
            'purchase_price': str(asset.purchase_price) if asset.purchase_price else '0',
            'current_value': str(asset.current_value),
            'image_url': asset.get_primary_image_url(),
            'qr_code_url': asset.get_qr_code_url(),
            'ledger': {
                'id': asset.ledger.id if asset.ledger else None,
                'name': asset.ledger.name if asset.ledger else '',
                'organization': {
                    'id': asset.ledger.organization.id if asset.ledger and asset.ledger.organization else None,
                    'name': asset.ledger.organization.name if asset.ledger and asset.ledger.organization else '',
                }
            },
        }
        
        return JsonResponse({
            'success': True,
            'asset': asset_data
        })
        
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'搜索失败: {str(e)}'
        })


@extend_schema(
    summary="资产列表API",
    parameters=[
        OpenApiParameter(name='page', description='页码', type=OpenApiTypes.INT),
        OpenApiParameter(name='page_size', description='每页数量', type=OpenApiTypes.INT),
        OpenApiParameter(name='search', description='搜索关键词', type=OpenApiTypes.STR),
        OpenApiParameter(name='category', description='分类ID', type=OpenApiTypes.INT),
        OpenApiParameter(name='status', description='状态', type=OpenApiTypes.STR),
        OpenApiParameter(name='department', description='部门ID', type=OpenApiTypes.INT),
        OpenApiParameter(name='organization', description='组织ID（按账簿所属组织过滤）', type=OpenApiTypes.INT),
        OpenApiParameter(name='ledger', description='账簿ID', type=OpenApiTypes.INT),
    ],
    responses={
        200: OpenApiTypes.OBJECT,
    }
)
@require_http_methods(["GET"])
@login_required
def asset_list_api(request):
    """资产列表API"""
    try:
        # 获取查询参数
        page = int(request.GET.get('page', 1))
        page_size = min(int(request.GET.get('page_size', 20)), 100)  # 限制最大页面大小
        search = request.GET.get('search', '').strip()
        category_id = request.GET.get('category')
        status = request.GET.get('status')
        department_id = request.GET.get('department')
        organization_id = request.GET.get('organization')
        ledger_id = request.GET.get('ledger')
        
        # 构建查询
        assets = Asset.objects.select_related(
            'category', 'department', 'location', 'user', 'ledger', 'ledger__organization'
        ).all()
        # 权限范围限制（非超级用户）
        if request.user.is_authenticated and not request.user.is_superuser:
            profile = getattr(request.user, 'profile', None)
            if profile:
                allowed_ledger_ids = list(profile.allowed_ledgers.values_list('id', flat=True))
                allowed_org_ids = list(profile.allowed_organizations.values_list('id', flat=True))
                if allowed_ledger_ids or allowed_org_ids:
                    scope_q = Q(ledger_id__in=allowed_ledger_ids)
                    if allowed_org_ids:
                        scope_q = scope_q | Q(ledger__organization_id__in=allowed_org_ids)
                    assets = assets.filter(scope_q)
        
        if search:
            assets = assets.filter(
                Q(asset_number__icontains=search) |
                Q(name__icontains=search)
            )
        
        if category_id:
            assets = assets.filter(category_id=category_id)
        
        if status:
            assets = assets.filter(status=status)
        
        if department_id:
            assets = assets.filter(department_id=department_id)
        
        if organization_id:
            assets = assets.filter(ledger__organization_id=organization_id)
        
        if ledger_id:
            assets = assets.filter(ledger_id=ledger_id)
        
        # 分页
        paginator = Paginator(assets, page_size)
        page_obj = paginator.get_page(page)
        
        # 构建返回数据
        asset_list = []
        for asset in page_obj:
            asset_list.append({
                'id': asset.id,
                'asset_number': asset.asset_number,
                'name': asset.name,
                'category': asset.category.name if asset.category else '',
                'department': asset.department.name if asset.department else '',
                'status': asset.status,
                'status_display': asset.get_status_display(),
                'image_url': asset.get_primary_image_url(),
                'ledger': {
                    'id': asset.ledger.id if asset.ledger else None,
                    'name': asset.ledger.name if asset.ledger else '',
                    'organization': {
                        'id': asset.ledger.organization.id if asset.ledger and asset.ledger.organization else None,
                        'name': asset.ledger.organization.name if asset.ledger and asset.ledger.organization else '',
                    }
                },
            })
        
        return JsonResponse({
            'success': True,
            'data': {
                'assets': asset_list,
                'pagination': {
                    'current_page': page_obj.number,
                    'total_pages': paginator.num_pages,
                    'total_count': paginator.count,
                    'has_next': page_obj.has_next(),
                    'has_previous': page_obj.has_previous(),
                }
            }
        })
        
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'获取资产列表失败: {str(e)}'
        })


@extend_schema(
    summary="资产详情API",
    parameters=[
        OpenApiParameter(name='asset_id', description='资产ID', type=OpenApiTypes.INT, location=OpenApiParameter.PATH),
    ],
    responses={
        200: OpenApiTypes.OBJECT,
    }
)
@require_http_methods(["GET"])
@login_required
def asset_detail_api(request, asset_id):
    """资产详情API"""
    try:
        asset = get_object_or_404(
            Asset.objects.select_related(
                'category', 'department', 'location', 'user', 'supplier'
            ).prefetch_related(
                'asset_images', 'maintenance_records', 'borrow_records'
            ),
            id=asset_id
        )
        
        # 获取维修记录
        maintenance_records = []
        for record in asset.maintenance_records.all()[:5]:  # 最近5条
            maintenance_records.append({
                'id': record.id,
                'title': record.title,
                'status': record.status,
                'status_display': record.get_status_display(),
                'reported_at': record.reported_at.strftime('%Y-%m-%d %H:%M'),
                'completed_at': record.completed_at.strftime('%Y-%m-%d %H:%M') if record.completed_at else None,
            })
        
        # 获取借用记录
        borrow_records = []
        for record in asset.borrow_records.all()[:5]:  # 最近5条
            borrow_records.append({
                'id': record.id,
                'borrower': record.borrower.username,
                'status': record.status,
                'status_display': record.get_status_display(),
                'created_at': record.created_at.strftime('%Y-%m-%d %H:%M'),
                'expected_return_date': record.expected_return_date.strftime('%Y-%m-%d %H:%M'),
            })
        
        # 获取所有图片
        images = asset.get_all_images()
        
        asset_data = {
            'id': asset.id,
            'asset_number': asset.asset_number,
            'name': asset.name,
            'category': {
                'id': asset.category.id if asset.category else None,
                'name': asset.category.name if asset.category else '',
            },
            'department': {
                'id': asset.department.id if asset.department else None,
                'name': asset.department.name if asset.department else '',
            },
            'location': {
                'id': asset.location.id if asset.location else None,
                'name': asset.location.name if asset.location else '',
            },
            'user': {
                'id': asset.user.id if asset.user else None,
                'username': asset.user.username if asset.user else '',
            },
            'supplier': {
                'id': asset.supplier.id if asset.supplier else None,
                'name': asset.supplier.name if asset.supplier else '',
            },
            'status': asset.status,
            'status_display': asset.get_status_display(),
            'purchase_date': asset.purchase_date.strftime('%Y-%m-%d') if asset.purchase_date else '',
            'purchase_price': str(asset.purchase_price) if asset.purchase_price else '0',
            'current_value': str(asset.current_value),
            'depreciation_rate': str(asset.depreciation_rate),
            'warranty_period': asset.warranty_period,
            'description': asset.description,
            'images': images,
            'qr_code_url': asset.get_qr_code_url(),
            'maintenance_records': maintenance_records,
            'borrow_records': borrow_records,
            'created_at': asset.created_at.strftime('%Y-%m-%d %H:%M'),
            'updated_at': asset.updated_at.strftime('%Y-%m-%d %H:%M'),
        }
        
        return JsonResponse({
            'success': True,
            'asset': asset_data
        })
        
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'获取资产详情失败: {str(e)}'
        })


@extend_schema(
    summary="我的通知API",
    parameters=[
        OpenApiParameter(name='page', description='页码', type=OpenApiTypes.INT),
        OpenApiParameter(name='page_size', description='每页数量', type=OpenApiTypes.INT),
        OpenApiParameter(name='unread_only', description='只显示未读', type=OpenApiTypes.BOOL),
    ],
    responses={
        200: OpenApiTypes.OBJECT,
    }
)
@require_http_methods(["GET"])
@login_required
def my_notifications_api(request):
    """我的通知API"""
    try:
        page = int(request.GET.get('page', 1))
        page_size = min(int(request.GET.get('page_size', 20)), 50)
        unread_only = request.GET.get('unread_only', 'false').lower() == 'true'
        
        notifications = SystemNotification.objects.filter(
            recipient=request.user
        )
        
        if unread_only:
            notifications = notifications.filter(is_read=False)
        
        # 分页
        paginator = Paginator(notifications, page_size)
        page_obj = paginator.get_page(page)
        
        notification_list = []
        for notification in page_obj:
            notification_list.append({
                'id': notification.id,
                'title': notification.title,
                'message': notification.message,
                'notification_type': notification.notification_type,
                'priority': notification.priority,
                'is_read': notification.is_read,
                'created_at': notification.created_at.strftime('%Y-%m-%d %H:%M:%S'),
                'read_at': notification.read_at.strftime('%Y-%m-%d %H:%M:%S') if notification.read_at else None,
                'related_url': notification.related_url,
            })
        
        return JsonResponse({
            'success': True,
            'data': {
                'notifications': notification_list,
                'pagination': {
                    'current_page': page_obj.number,
                    'total_pages': paginator.num_pages,
                    'total_count': paginator.count,
                    'has_next': page_obj.has_next(),
                    'has_previous': page_obj.has_previous(),
                },
                'unread_count': SystemNotification.objects.filter(
                    recipient=request.user, is_read=False
                ).count()
            }
        })
        
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'获取通知失败: {str(e)}'
        })


@extend_schema(
    summary="标记通知为已读API",
    parameters=[
        OpenApiParameter(name='notification_id', description='通知ID', type=OpenApiTypes.INT, location=OpenApiParameter.PATH),
    ],
    responses={
        200: OpenApiTypes.OBJECT,
    }
)
@require_http_methods(["POST"])
@login_required
@csrf_exempt
def mark_notification_read_api(request, notification_id):
    """标记通知为已读API"""
    try:
        notification = get_object_or_404(
            SystemNotification,
            id=notification_id,
            recipient=request.user
        )
        
        notification.mark_as_read()
        
        return JsonResponse({
            'success': True,
            'message': '通知已标记为已读'
        })
        
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'操作失败: {str(e)}'
        })


@extend_schema(
    summary="我的借用记录API",
    parameters=[
        OpenApiParameter(name='page', description='页码', type=OpenApiTypes.INT),
        OpenApiParameter(name='page_size', description='每页数量', type=OpenApiTypes.INT),
        OpenApiParameter(name='status', description='状态', type=OpenApiTypes.STR),
    ],
    responses={
        200: OpenApiTypes.OBJECT,
    }
)
@require_http_methods(["GET"])
@login_required
def my_borrows_api(request):
    """我的借用记录API"""
    try:
        page = int(request.GET.get('page', 1))
        page_size = min(int(request.GET.get('page_size', 20)), 50)
        status = request.GET.get('status')
        
        borrows = AssetBorrow.objects.filter(
            borrower=request.user
        ).select_related('asset', 'asset__category')
        
        if status:
            borrows = borrows.filter(status=status)
        
        # 分页
        paginator = Paginator(borrows, page_size)
        page_obj = paginator.get_page(page)
        
        borrow_list = []
        for borrow in page_obj:
            borrow_list.append({
                'id': borrow.id,
                'asset': {
                    'id': borrow.asset.id,
                    'asset_number': borrow.asset.asset_number,
                    'name': borrow.asset.name,
                    'category': borrow.asset.category.name if borrow.asset.category else '',
                },
                'status': borrow.status,
                'status_display': borrow.get_status_display(),
                'purpose': borrow.get_purpose_display(),
                'expected_return_date': borrow.expected_return_date.strftime('%Y-%m-%d %H:%M'),
                'created_at': borrow.created_at.strftime('%Y-%m-%d %H:%M'),
                'is_overdue': borrow.is_overdue,
            })
        
        return JsonResponse({
            'success': True,
            'data': {
                'borrows': borrow_list,
                'pagination': {
                    'current_page': page_obj.number,
                    'total_pages': paginator.num_pages,
                    'total_count': paginator.count,
                    'has_next': page_obj.has_next(),
                    'has_previous': page_obj.has_previous(),
                }
            }
        })
        
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'获取借用记录失败: {str(e)}'
        })


@extend_schema(
    summary="资产类别API",
    responses={
        200: OpenApiTypes.OBJECT,
    }
)
@require_http_methods(["GET"])
def categories_api(request):
    """资产类别API"""
    try:
        categories = AssetCategory.objects.all().order_by('name')
        
        category_list = []
        for category in categories:
            category_list.append({
                'id': category.id,
                'name': category.name,
                'code': category.code,
                'asset_count': category.asset_set.count(),
            })
        
        return JsonResponse({
            'success': True,
            'categories': category_list
        })
        
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'获取类别失败: {str(e)}'
        })


@extend_schema(
    summary="部门API",
    responses={
        200: OpenApiTypes.OBJECT,
    }
)
@require_http_methods(["GET"])
def departments_api(request):
    """部门API"""
    try:
        departments = Department.objects.select_related('organization').all().order_by('name')
        
        department_list = []
        for dept in departments:
            department_list.append({
                'id': dept.id,
                'name': dept.name,
                'code': dept.code,
                'organization': dept.organization.name if dept.organization else '',
                'asset_count': dept.asset_set.count(),
            })
        
        return JsonResponse({
            'success': True,
            'departments': department_list
        })
        
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'获取部门失败: {str(e)}'
        })


@extend_schema(
    summary="同步离线数据API",
    request=OpenApiTypes.OBJECT,
    responses={
        200: OpenApiTypes.OBJECT,
    }
)
@require_http_methods(["POST"])
@csrf_exempt
def sync_offline_data_api(request):
    """同步离线数据API"""
    try:
        data = json.loads(request.body)
        
        # 这里处理离线数据同步逻辑
        # 例如：离线创建的借用申请、维修申请等
        
        sync_results = []
        
        for item in data.get('items', []):
            item_type = item.get('type')
            item_data = item.get('data')
            
            if item_type == 'borrow_request':
                # 处理借用申请
                result = sync_borrow_request(item_data)
                sync_results.append(result)
            elif item_type == 'maintenance_request':
                # 处理维修申请
                result = sync_maintenance_request(item_data)
                sync_results.append(result)
            # 可以添加更多类型的同步处理
        
        return JsonResponse({
            'success': True,
            'message': '数据同步完成',
            'results': sync_results
        })
        
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'数据同步失败: {str(e)}'
        })


def sync_borrow_request(data):
    """同步借用申请"""
    try:
        # 这里实现借用申请的同步逻辑
        return {
            'type': 'borrow_request',
            'status': 'success',
            'message': '借用申请同步成功'
        }
    except Exception as e:
        return {
            'type': 'borrow_request',
            'status': 'error',
            'message': f'借用申请同步失败: {str(e)}'
        }


def sync_maintenance_request(data):
    """同步维修申请"""
    try:
        # 这里实现维修申请的同步逻辑
        return {
            'type': 'maintenance_request',
            'status': 'success',
            'message': '维修申请同步成功'
        }
    except Exception as e:
        return {
            'type': 'maintenance_request',
            'status': 'error',
            'message': f'维修申请同步失败: {str(e)}'
        }